home *** CD-ROM | disk | FTP | other *** search
/ Aminet 7 / Aminet 7 - August 1995.iso / Aminet / text / hyper / ADtoHT2_1.lha / Source.lha / MyLib.lha / programs / AsmStub.c next >
Encoding:
C/C++ Source or Header  |  1995-04-22  |  10.2 KB  |  501 lines

  1. #include <proto/dos.h>
  2.  
  3. #include <stdio.h>
  4. #include <errno.h>
  5. #include <ctype.h>
  6. #include <Amiga.h>
  7.  
  8. /************************************************************************/
  9.  
  10. char VersionString[]="$VER: AsmStub 1.0 (17.04.95)© 1995 Christian Stieber";
  11.  
  12. /************************************************************************/
  13.  
  14. #define REGISTER_COUNT    15
  15. #define REGISTER_A4    12
  16.  
  17. static struct
  18. {
  19.   long Registers[REGISTER_COUNT];
  20.   long Saveds;
  21.   long Static;
  22.   long Interrupt;
  23.   long InterruptBug;
  24. } Arguments;
  25.  
  26. static int RegisterCount;
  27.  
  28. static const char *RegisterName[REGISTER_COUNT]=
  29. {
  30.   "d0","d1","d2","d3","d4","d5","d6","d7",
  31.   "a0","a1","a2","a3","a4","a5","a6"
  32. };
  33.  
  34. static int RC;
  35.  
  36. /************************************************************************/
  37.  
  38. static void OutputMacroName(int Prototype)
  39.  
  40. {
  41.   int Register;
  42.   int Underscore;
  43.  
  44.   Underscore=FALSE;
  45.   if (Arguments.Static)
  46.     {
  47.       printf("STATIC");
  48.       Underscore=TRUE;
  49.     }
  50.   if (Arguments.Saveds)
  51.     {
  52.       if (Underscore)
  53.     {
  54.       printf("_");
  55.     }
  56.       printf("SAVEDS");
  57.       Underscore=TRUE;
  58.     }
  59.   if (Arguments.Interrupt)
  60.     {
  61.       if (Underscore)
  62.     {
  63.       printf("_");
  64.     }
  65.       printf("INTERRUPT");
  66.       if (Arguments.InterruptBug)
  67.     {
  68.       printf("BUG");
  69.     }
  70.       Underscore=TRUE;
  71.     }
  72.   if (RegisterCount!=0)
  73.     {
  74.       if (Underscore)
  75.     {
  76.       printf("_");
  77.     }
  78.       printf("ASM_");
  79.       for (Register=0; Register<REGISTER_COUNT; Register++)
  80.     {
  81.       if (Arguments.Registers[Register])
  82.         {
  83.           const char *t;
  84.  
  85.           for (t=RegisterName[Register]; *t; t++)
  86.         {
  87.           printf("%lc",(long)toupper(*t));
  88.         }
  89.         }
  90.     }
  91.       Underscore=TRUE;
  92.     }
  93.   if (Prototype)
  94.     {
  95.       if (Underscore)
  96.     {
  97.       printf("_");
  98.     }
  99.       printf("PROTO");
  100.     }
  101.   printf("(ReturnType,FuncName");
  102.   for (Register=0; Register<REGISTER_COUNT; Register++)
  103.     {
  104.       if (Arguments.Registers[Register])
  105.     {
  106.       printf(",%sType",RegisterName[Register]);
  107.       if (!Prototype)
  108.         {
  109.           printf(",%sName",RegisterName[Register]);
  110.         }
  111.     }
  112.     }
  113.   printf(")");
  114. }
  115.  
  116. /************************************************************************/
  117.  
  118. static void CreateSAS5Macros(void)
  119.  
  120. {
  121.   int Prototype;
  122.  
  123.   printf("#ifdef __SASC\n");
  124.   for (Prototype=1; Prototype>=0; Prototype--)
  125.     {
  126.       printf("#define ");
  127.       OutputMacroName(Prototype);
  128.       if (Arguments.Static)
  129.     {
  130.       printf(" static");
  131.     }
  132.       printf(" ReturnType ");
  133.       if (Arguments.Saveds)
  134.     {
  135.       printf("__SAVEDS ");
  136.     }
  137.       if (Arguments.Interrupt)
  138.     {
  139.       printf("interrupt_not_implemented ");
  140.     }
  141.       if (RegisterCount!=0)
  142.     {
  143.       int Register;
  144.       int Count;
  145.  
  146.       printf("__asm FuncName(");
  147.       Count=0;
  148.       for (Register=0; Register<REGISTER_COUNT; Register++)
  149.         {
  150.           if (Arguments.Registers[Register])
  151.         {
  152.           if (Count!=0)
  153.             {
  154.               printf(", ");
  155.             }
  156.           printf("register __%s %sType",RegisterName[Register],RegisterName[Register]);
  157.           if (!Prototype)
  158.             {
  159.               printf(" %sName",RegisterName[Register]);
  160.             }
  161.           Count++;
  162.         }
  163.         }
  164.       printf(")\n");
  165.     }
  166.       else
  167.     {
  168.       printf("FuncName(void)\n");
  169.     }
  170.     }
  171.   printf("#endif  /* __SASC */\n");
  172. }
  173.  
  174. /************************************************************************/
  175.  
  176. #define MODEL_SMALLCODE    (1<<0)
  177. #define MODEL_SMALLDATA    (1<<1)
  178.  
  179. static INLINE void GNUCCall(int AdressingType, const char *FuncName)
  180.  
  181. {
  182.   if (AdressingType&MODEL_SMALLCODE)
  183.     {
  184.       printf("\tjsr PC@(%s+2)\n",FuncName);
  185.     }
  186.   else
  187.     {
  188.       printf("\tjsr %s\n",FuncName);
  189.     }
  190. }
  191.  
  192. /*----------------------------------------------------------------------*/
  193.  
  194. static void GNUCOutputFunctionHeader(const char *Name)
  195.  
  196. {
  197.   int Register;
  198.   int Count;
  199.  
  200.   printf("ReturnType %s(",Name);
  201.   Count=0;
  202.   for (Register=0; Register<REGISTER_COUNT; Register++)
  203.     {
  204.       if (Arguments.Registers[Register])
  205.     {
  206.       if (Count!=0)
  207.         {
  208.           printf(", ");
  209.         }
  210.       printf("%sType %sName",RegisterName[Register],RegisterName[Register]);
  211.       Count++;
  212.     }
  213.     }
  214.   if (Count==0)
  215.     {
  216.       printf("void");
  217.     }
  218.   printf(")\n");
  219. }
  220.  
  221. /*----------------------------------------------------------------------*/
  222.  
  223. static void CreateGNUCMacros(void)
  224.  
  225. {
  226.   int AdressingType;
  227.  
  228.   printf("#ifdef __GNUC__\n");
  229.   for (AdressingType=MODEL_SMALLCODE|MODEL_SMALLDATA; AdressingType>=0; AdressingType--)
  230.     {
  231.       int Prototype;
  232.  
  233.       printf("#if ");
  234.       if (!(AdressingType&MODEL_SMALLDATA))
  235.     {
  236.       printf("!");
  237.     }
  238.       printf("defined(SMALL_DATA) && ");
  239.       if (!(AdressingType&MODEL_SMALLCODE))
  240.     {
  241.       printf("!");
  242.     }
  243.       printf("defined(SMALL_CODE)\n");
  244.  
  245.       for (Prototype=1; Prototype>=0; Prototype--)
  246.     {
  247.       printf("#define ");
  248.       OutputMacroName(Prototype);
  249.       if (Prototype)
  250.         {
  251.           if (Arguments.Static)
  252.         {
  253.           printf(" static");
  254.         }
  255.           printf(" ReturnType FuncName(void)\n");
  256.         }
  257.       else
  258.         {
  259.           printf(" ");
  260.           if ((!(AdressingType&MODEL_SMALLDATA) || !Arguments.Saveds) && RegisterCount==0 && !Arguments.Interrupt)
  261.         {
  262.           /* we don't need stub code */
  263.           if (Arguments.Static)
  264.             {
  265.               printf("static ");
  266.             }
  267.           GNUCOutputFunctionHeader("FuncName");
  268.         }
  269.           else
  270.         {
  271.           OutputMacroName(TRUE);
  272.           printf("; asm(\x22 .text\n");
  273.           if (!Arguments.Static)
  274.             {
  275.               printf("\t.globl _\x22 #FuncName \x22\n");
  276.             }
  277.           printf("_\x22 #FuncName \x22:\n");
  278.           if ((!(AdressingType&MODEL_SMALLDATA) || !Arguments.Saveds) && RegisterCount==0)
  279.             {
  280.               GNUCCall(AdressingType,"___AsmEntry\x22 #FuncName \x22");
  281.             }
  282.           else if (Arguments.Saveds && (RegisterCount==0 || (RegisterCount==1 && Arguments.Registers[REGISTER_A4])))
  283.             {
  284.               if (Arguments.Interrupt && RegisterCount==0)
  285.             {
  286.               /* I'm using a5, since using a6 would make it unusable for softints */
  287.               printf("\tmovl a4,a5\n");
  288.             }
  289.               else
  290.             {
  291.               printf("\tmovl a4,SP@-\n");
  292.             }
  293.               if (AdressingType&MODEL_SMALLDATA)
  294.             {
  295.               GNUCCall(AdressingType,"__geta4");
  296.             }
  297.               GNUCCall(AdressingType,"___AsmEntry\x22 #FuncName \x22");
  298.               if (Arguments.Interrupt && RegisterCount==0)
  299.             {
  300.               printf("\tmovl a5,a4\n");
  301.             }
  302.               else
  303.             {
  304.               if (AdressingType&MODEL_SMALLDATA)
  305.                 {
  306.                   printf("\tmovl SP@+,a4\n");
  307.                 }
  308.               else
  309.                 {
  310.                   printf("\taddql #4,SP\n");
  311.                 }
  312.             }
  313.             }
  314.           else if (RegisterCount==1 && (!(AdressingType&MODEL_SMALLDATA) || !Arguments.Saveds))
  315.             {
  316.               int Register;
  317.  
  318.               for (Register=REGISTER_COUNT-1; !Arguments.Registers[Register]; Register--)
  319.             ;
  320.               printf("\tmovl %s,SP@-\n",RegisterName[Register]);
  321.               GNUCCall(AdressingType,"___AsmEntry\x22 #FuncName \x22");
  322.               printf("\taddql #4,SP\n");
  323.             }
  324.           else /* RegisterCount>1 */
  325.             {
  326.               int Count;
  327.               int Register;
  328.               int PreA4, PostA4;
  329.               int RealRegisterCount;
  330.  
  331.               printf("\tmovml ");
  332.               Count=0;
  333.               PreA4=PostA4=0;
  334.               RealRegisterCount=0;
  335.               for (Register=0; Register<REGISTER_COUNT; Register++)
  336.             {
  337.               if (Arguments.Registers[Register])
  338.                 {
  339.                   if (Count!=0)
  340.                 {
  341.                   printf("/");
  342.                 }
  343.                   printf(RegisterName[Register]);
  344.                   Count++;
  345.                   if (Register<REGISTER_A4)
  346.                 {
  347.                   PreA4++;
  348.                 }
  349.                   else if (Register>REGISTER_A4)
  350.                 {
  351.                   PostA4++;
  352.                 }
  353.                   RealRegisterCount++;
  354.                 }
  355.             }
  356.               if (Arguments.Saveds &&
  357.               (AdressingType&MODEL_SMALLDATA) &&
  358.               !Arguments.Registers[REGISTER_A4])
  359.             {
  360.               printf("/a4");
  361.               RealRegisterCount++;
  362.             }
  363.               printf(",SP@-\n");
  364.               if (Arguments.Saveds && (AdressingType&MODEL_SMALLDATA))
  365.             {
  366.               GNUCCall(AdressingType,"__geta4");
  367.             }
  368.               GNUCCall(AdressingType,"___AsmEntry\x22 #FuncName \x22");
  369.               if (PostA4==0)
  370.             {
  371.               if (Arguments.Saveds && (AdressingType&MODEL_SMALLDATA))
  372.                 {
  373.                   RealRegisterCount--;
  374.                 }
  375.               if (RealRegisterCount<=2)
  376.                 {
  377.                   printf("\taddql #%ld,SP\n",(long)(RealRegisterCount*4));
  378.                 }
  379.               else
  380.                 {
  381.                   printf("\tlea SP@(%ld),SP\n",(long)(RealRegisterCount*4));
  382.                 }
  383.               if (Arguments.Saveds && (AdressingType&MODEL_SMALLDATA))
  384.                 {
  385.                   printf("\tmovl SP@+,a4\n");
  386.                 }
  387.             }
  388.               else  /* PostA4 != 0 */
  389.             {
  390.               if (Arguments.Saveds && (AdressingType&MODEL_SMALLDATA))
  391.                 {
  392.                   if (PreA4==0)
  393.                 {
  394.                   if (PostA4==1)
  395.                     {
  396.                       printf("\tmovl SP@,a4\n");
  397.                       printf("\taddql #8,SP\n");
  398.                     }
  399.                   else /* (PostA4==2) */
  400.                     {
  401.                       printf("\tmovl SP@+,a4\n");
  402.                       printf("\taddql #8,SP\n");
  403.                     }
  404.                 }
  405.                   else  /* PreA4!=0 */
  406.                 {
  407.                   printf("\tmovl SP@(%ld),a4\n",(long)(PreA4*4));
  408.                   printf("\tlea SP@(%ld),SP\n",(long)(RealRegisterCount*4));
  409.                 }
  410.                 }
  411.               else
  412.                 {
  413.                   if (RealRegisterCount<=2)
  414.                 {
  415.                   printf("\taddql #%ld,SP\n",(long)(RealRegisterCount*4));
  416.                 }
  417.                   else
  418.                 {
  419.                   printf("\tlea SP@(%ld),SP\n",(long)(RealRegisterCount*4));
  420.                 }
  421.                 }
  422.             }
  423.             }
  424.           if (Arguments.Interrupt)
  425.             {
  426.               if (Arguments.InterruptBug)
  427.             {
  428.               printf("\tmovl #$00dff000,a0\n");
  429.             }
  430.               printf("\ttstl d0\n");
  431.             }
  432.           printf("\trts\x22); static ");
  433.           GNUCOutputFunctionHeader("__AsmEntry##FuncName");
  434.         }
  435.         }
  436.     }
  437.       printf("#endif  /* ");
  438.       if (!(AdressingType&MODEL_SMALLDATA))
  439.     {
  440.       printf("!");
  441.     }
  442.       printf("defined(SMALL_DATA) && ");
  443.       if (!(AdressingType&MODEL_SMALLCODE))
  444.     {
  445.       printf("!");
  446.     }
  447.       printf("defined(SMALL_CODE) */\n");
  448.  
  449.     }
  450.   printf("#endif  /* __GNUC__ */\n");
  451. }
  452.  
  453. /************************************************************************/
  454.  
  455. int AmigaMain(void)
  456.  
  457. {
  458.   struct RDArgs *RDArgs;
  459.  
  460.   RC=RETURN_OK;
  461.   if (!WorkbenchMessage)
  462.     {
  463.       if ((RDArgs=ReadArgs("D0/S,D1/S,D2/S,D3/S,D4/S,D5/S,D6/S,D7/S,A0/S,A1/S,A2/S,A3/S,A4/S,A5/S,A6/S,SAVEDS/S,STATIC/S,INTERRUPT/S,INTERRUPTBUG/S",(long *)&Arguments,NULL)))
  464.     {
  465.       int Register;
  466.  
  467.       if (Arguments.InterruptBug)
  468.         {
  469.           Arguments.Interrupt=TRUE;
  470.         }
  471.       if (Arguments.Interrupt)
  472.         {
  473.           Arguments.Saveds=TRUE;
  474.         }
  475.       for (Register=0; Register<REGISTER_COUNT; Register++)
  476.         {
  477.           if (Arguments.Registers[Register])
  478.         {
  479.           RegisterCount++;
  480.         }
  481.         }
  482.       printf("/* This file was generated automatically. */\n"
  483.          "/* Do not edit.                           */\n\n");
  484.       CreateSAS5Macros();
  485.       printf("\n");
  486.       CreateGNUCMacros();
  487.     }
  488.       else
  489.     {
  490.       errno=IoErr();
  491.       perror(NULL);
  492.       RC=RETURN_FAIL;
  493.     }
  494.     }
  495.   else
  496.     {
  497.       RC=RETURN_CATASTROPHY;
  498.     }
  499.   return RC;
  500. }
  501.